package br.ufrj.ppgi.infovis.mtgraph;

import org.mt4j.components.MTComponent;
import org.mt4j.components.visibleComponents.widgets.keyboard.MTKeyboard;
import org.mt4j.input.gestureAction.TapAndHoldVisualizer;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.AbstractComponentProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateEvent;
import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.tapAndHoldProcessor.TapAndHoldEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapAndHoldProcessor.TapAndHoldProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapProcessor;
import org.mt4j.util.math.Vector3D;

import br.ufrj.ppgi.infovis.mtgraph.shapes.LabeledCircle;

public class GraphNodeGestures {
	
	private GraphScene scene;
	private GraphNode node;
	private MTComponent texto;
	private MTKeyboard kb;
	
	public GraphNodeGestures(GraphScene scene, GraphNode Node) {
		this.scene = scene;
		this.node = Node;
		this.texto = Node.getComponent();
		this.clearAllGestures(this.texto);				
	}

	//Gestures
	public void addGestures() {
		this.addTap();
		this.addDoubleTap();
		this.addTapHold();
	}

	//TAP
	public void addTap() {
		this.texto.registerInputProcessor(new TapProcessor(this.scene.getMTApplication(), 25));
		this.texto.addGestureListener(TapProcessor.class, new IGestureEventListener() {
			public boolean processGestureEvent(MTGestureEvent ge) {
				TapEvent te = (TapEvent)ge;
				if (te.isTapped()){
					Tap();
				}
				return false;
			}
		});		
	}
	
	//DOUBLETAP
	public void addDoubleTap() {
		this.texto.registerInputProcessor(new TapProcessor(this.scene.getMTApplication(), 25, true, 350));
		this.texto.addGestureListener(TapProcessor.class, new IGestureEventListener() {
			public boolean processGestureEvent(MTGestureEvent ge) {
				TapEvent te = (TapEvent)ge;
				if (te.isDoubleTap()){
					DoubleTap();
				}
				return false;
			}
		});		
	}
	
	//TAP&HOLD
	public void addTapHold() {
		this.texto.registerInputProcessor(new TapAndHoldProcessor(this.scene.getMTApplication(), 2000));
		this.texto.addGestureListener(TapAndHoldProcessor.class, new TapAndHoldVisualizer(this.scene.getMTApplication(), this.scene.getCanvas()));
		this.texto.addGestureListener(TapAndHoldProcessor.class, new IGestureEventListener() {
			public boolean processGestureEvent(MTGestureEvent ge) {
				TapAndHoldEvent th = (TapAndHoldEvent)ge;
				switch (th.getId()) {
				case TapAndHoldEvent.GESTURE_STARTED:
					break;
				case TapAndHoldEvent.GESTURE_UPDATED:
					break;
				case TapAndHoldEvent.GESTURE_ENDED:
					if (th.isHoldComplete()){
						TapHold();
					}
					break;
				default:
					break;
				}
				return false;
			}
		});	
	}
	
	
	private void clearAllGestures(MTComponent comp){
		//comp.unregisterAllInputProcessors();
		
		for (AbstractComponentProcessor ip : comp.getInputProcessors()){
			if ( !(ip instanceof ScaleProcessor ||
				ip instanceof RotateProcessor ||
				ip instanceof DragProcessor )) {
				comp.unregisterInputProcessor(ip);
			}
		}
		
		
		comp.removeAllGestureEventListeners(TapProcessor.class);
		comp.removeAllGestureEventListeners(TapAndHoldProcessor.class);
	}
	
	private void Tap() {
		if (this.scene.getSelectionEvent()) {
			this.node.setSelected(true);
		}
	}
	
	private void DoubleTap() {
		//System.out.println("double tap");		
		//Brings a keyboard to the front of the screen with which the text can be modified.
		if (this.kb != null) {
			this.kb.destroy();
		}
		
		LabeledCircle lc = (LabeledCircle) this.texto;
		//Cria o teclado
		this.kb = new MTKeyboard(this.scene.getMTApplication());
		//Linka o teclado com o MTTextArea interno ao LabeledCircle
		this.kb.addTextInputListener(lc);
		//Link o teclado com o teclado fisico
		this.scene.setTextInputListener(lc);
		//Adiciona o teclado no cenario
		this.scene.getCanvas().addChild(this.kb);
		//Posiciona o teclado abaixo do No (circulo)
		this.kb.setPositionGlobal(new Vector3D(lc.getX(), lc.getY() + 150));
	}
	
	private void TapHold() {
		//Exclusao
		this.scene.DeleteNode(false, this.node);
		//Fecha teclado se estiver aberto
		if (this.kb != null) {
			this.kb.destroy();			
		}
	}
}
